package com.youlu.campus.service.english;

import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.english.*;
import com.youlu.campus.entity.english.vo.request.ImportQaRankingRequest;
import com.youlu.campus.entity.english.vo.request.QaRankingQuery;
import com.youlu.campus.entity.english.vo.response.UserCompetitionInviteRanking;
import com.youlu.campus.entity.english.vo.response.UserCompetitionQaRanking;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;

@Slf4j
@Service
public class UserCompetitionRankingService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ActivityTaskService activityTaskService;

    @Autowired
    private UserCompetitionService userCompetitionService;

    @Autowired
    private ActivityGroupService activityGroupService;


    public void importQaRanking(List<ImportQaRankingRequest> importQaRankingDataList){
        importQaRankingDataList.parallelStream().forEach(importQaRanking -> {
            doImportQaRaning(importQaRanking);
        });
    }

    private void doImportQaRaning(ImportQaRankingRequest importQaRankingRequest){
        UserCompetition userCompetition = userCompetitionService.findByMobile(importQaRankingRequest.getMobile());
        if(Objects.isNull(userCompetition)){
            log.error("用户手机号->{} 不存在",importQaRankingRequest.getMobile());
            return;
        }
        ActivityGroup activityGroup = activityGroupService.findById(importQaRankingRequest.getGroupId());
        if(Objects.isNull(activityGroup)){
            log.error("用户->{}所属组别->{}不存在->{}",importQaRankingRequest.getMobile(),importQaRankingRequest.getGroupId());
            return;
        }
        Optional<ActivityGroupQaType> groupQaTypeOptional = null;
        switch (importQaRankingRequest.getQaType()){
            case 1:
                groupQaTypeOptional = activityGroup.getQaTypeList().stream().filter(qaType -> ActivityGroupQaType.QA_CHU_SAI.equals(qaType.getCode())).findAny();
                break;
            case 2:
                groupQaTypeOptional = activityGroup.getQaTypeList().stream().filter(qaType -> ActivityGroupQaType.QA_FU_SAI.equals(qaType.getCode())).findAny();
                break;
            case 3:
                groupQaTypeOptional = activityGroup.getQaTypeList().stream().filter(qaType -> ActivityGroupQaType.QA_JUE_SAI.equals(qaType.getCode())).findAny();
                break;
                default:
        }
        if(Objects.isNull(groupQaTypeOptional) ||!groupQaTypeOptional.isPresent()){
            log.error("用户->{}所属组别->{}不存在->{} 答题找不到",importQaRankingRequest.getMobile(), importQaRankingRequest.getGroupId());
            return;
        }
        ActivityGroupQaType activityGroupQaType = groupQaTypeOptional.get();
        String orderTime = importQaRankingRequest.getOrderTime();
        try {
            Date currentDate = DateUtils.parseDate(orderTime, "yyyy-MM-dd HH:mm:ss");
            Query query = new Query();
            query.addCriteria(Criteria.where("userId").is(userCompetition.getUserId()));
            query.addCriteria(Criteria.where("activityGroupId").is(activityGroup.getId()));
            query.addCriteria(Criteria.where("qaInfoId").is(activityGroupQaType.getQaInfoId()));
            UserCompetitionQa userCompetitionQa = this.mongoTemplate.findOne(query, UserCompetitionQa.class);
            if(Objects.isNull(userCompetitionQa)){
                userCompetitionQa = new UserCompetitionQa();
                userCompetitionQa.setUserId(userCompetition.getUserId());
                userCompetitionQa.setQaType("QA");
                userCompetitionQa.setActivityGroupName(activityGroup.getGroupName());
                userCompetitionQa.setQaInfoId(activityGroupQaType.getQaInfoId());
                userCompetitionQa.setQaCode(activityGroupQaType.getCode());
                userCompetitionQa.setNickName(userCompetition.getNickName());
                userCompetitionQa.setName(userCompetition.getName());
                userCompetitionQa.setAvatarUrl(userCompetition.getAvatarUrl());
                userCompetitionQa.setActivityGroupId(activityGroup.getId());
            }
            userCompetitionQa.setCaLevel(importQaRankingRequest.getLevel());
            userCompetitionQa.setScore(importQaRankingRequest.getScore());
            userCompetitionQa.setUniversityName(importQaRankingRequest.getUniversityName());
            userCompetitionQa.setCreatedTime(currentDate);
            ScoreMappingLevel scoreMappingLevel = new ScoreMappingLevel();
            scoreMappingLevel.setScore(importQaRankingRequest.getScore());
            scoreMappingLevel.setLevel(importQaRankingRequest.getLevel());
            List<ScoreMappingLevel> scoreMappingLevelList = new ArrayList<>(1);
            scoreMappingLevelList.add(scoreMappingLevel);
            userCompetitionQa.setQaScoreLevelList(scoreMappingLevelList);
            this.mongoTemplate.save(userCompetitionQa);
        } catch (ParseException e) {
            e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }



    public List<UserCompetitionQaRanking> userQaList(QaRankingQuery qaRankingQuery){

        Aggregation aggregation =
                Aggregation.newAggregation(
                        Aggregation.match(Criteria.where("qaInfoId").is(qaRankingQuery.getQaInfoId()).
                                and("qaCode").is(qaRankingQuery.getQaCode()).
                                and("activityGroupId").is(qaRankingQuery.getActivityGroupId()).and("score").gt(0)),
                        Aggregation.group("userId").
                                max("score").as("score").
                                max("nickName").as("nickName").
                                max("avatarUrl").as("avatarUrl").
                        max("universityName").as("universityName").
                                max("createdTime").as("createdTime"),
                        Aggregation.sort(Sort.by(Sort.Order.desc("score"),Sort.Order.asc("createdTime"))),
                        Aggregation.skip((qaRankingQuery.getPageNo()-1)*qaRankingQuery.getPageSize()),
                Aggregation.limit(qaRankingQuery.getPageSize()));
        AggregationResults<UserCompetitionQaRanking> results = this.mongoTemplate.aggregate(aggregation, "userCompetitionQa", UserCompetitionQaRanking.class);
        if(CollectionUtils.isEmpty(results.getMappedResults())){
            return null;
        }
        return results.getMappedResults();
    }

    public List<UserCompetitionInviteRanking> inviteRanking(String activityId,Integer pageNo,Integer pageSize){
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        Aggregation aggregation =
                Aggregation.newAggregation(
                        Aggregation.match(Criteria.where("activityId").is(activityId).
                                and("taskId").is(activityTaskInfo.getId()).
                                and("joinStatus").is(Boolean.TRUE)),
                        Aggregation.group("invitedByUserId").count().as("inviteCount").
                                max("invitedByUserName").as("invitedByUserName").
                                max("invitedByUserImageUrl").as("invitedByUserImageUrl"),
                        Aggregation.sort(Sort.Direction.DESC,"inviteCount"),
                        Aggregation.skip((pageNo-1)*pageSize),
                        Aggregation.limit(pageSize));
        AggregationResults<UserCompetitionInviteRanking> results = this.mongoTemplate.aggregate(aggregation, "user_invite_record",
                UserCompetitionInviteRanking.class);
        if(CollectionUtils.isEmpty(results.getMappedResults())){
            return null;
        }
        return results.getMappedResults();
    }



}
